package com.mall.shopping.services;

import com.alibaba.fastjson.JSON;
import com.mall.shopping.ICartService;
import com.mall.shopping.constants.ShoppingRetCode;
import com.mall.shopping.converter.CartProductConverter;
import com.mall.shopping.dto.*;
import com.mall.shopping.utils.ExceptionProcessorUtils;
import com.mall.shopping.utils.ICartUserUtils;
import lombok.extern.slf4j.Slf4j;
import com.mall.shopping.converter.ProductConverter;
import com.mall.shopping.dal.entitys.Item;
import com.mall.shopping.dal.persistence.ItemMapper;
import org.apache.dubbo.config.annotation.Service;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


import java.util.*;

/**
 * @author
 * @date 2020/12/21 13:35
 */
@Slf4j
@Service
@Component
public class CartServiceImpl implements ICartService {
    @Autowired
    RedissonClient redissonClient;
    @Autowired
    ItemMapper itemMapper;
    @Autowired
    ProductConverter converter;
    @Autowired
    CartProductConverter cartProductConverter;
    /**
     * 获得购物车商品列表
     *
     * @param request
     * @return
     */
    @Override
    public CartListByIdResponse getCartListById(CartListByIdRequest request) {
        log.warn("init CartServiceImpl.getCartListById request: {}",request);
        CartListByIdResponse response = new CartListByIdResponse();
        try {
            request.requestCheck();
            RMap<Long, CartProductDto> map = redissonClient.getMap((request.getUserId().toString()));
            Set<Map.Entry<Long, CartProductDto>> entries = map.readAllEntrySet();
            List<CartProductDto> list = new ArrayList();
            for (Map.Entry<Long, CartProductDto> entry : entries) {
                CartProductDto value = entry.getValue();
                //CartProductDto cartProductDto = JSON.parseObject(value, CartProductDto.class);
                list.add(value);
            }
            response.setCartProductDtos(list);
            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            log.error("CartServiceImpl.getCartListById occur Exception: {}", e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }


    /**
     * 添加商品到购物车
     *
     * @param request
     * @return
     */
    @Override
    public AddCartResponse addToCart(AddCartRequest request) {
        AddCartResponse response = new AddCartResponse();

        RMap<Long, CartProductDto> rMap = redissonClient.getMap(request.getUserId().toString());
        if (rMap.containsKey(request.getItemId())){
            CartProductDto cartProductDto = rMap.get(request.getItemId());
            Long productNum = cartProductDto.getProductNum() + request.getNum();
            cartProductDto.setProductNum(productNum);
            rMap.put(request.getItemId(),cartProductDto);
        }else {
            Item item = itemMapper.selectByPrimaryKey(request.getItemId());
            CartProductDto cartProductDto = converter.item2CartDto(item);
            cartProductDto.setProductNum(request.getNum().longValue());
            cartProductDto.setChecked("true");
            rMap.put(request.getItemId(),cartProductDto);
        }
        Set<Map.Entry<Long, CartProductDto>> entries = rMap.readAllEntrySet();
        Iterator<Map.Entry<Long, CartProductDto>> iterator = entries.iterator();
        while(iterator.hasNext()){
            Map.Entry<Long, CartProductDto> next = iterator.next();
            System.out.println(next);
        }

        response.setCode("200");
        response.setMsg("成功");
        return response;
    }

    /**
     * 更新购物车中商品的数量
     *
     * @param request
     * @return
     */
    @Override
    public UpdateCartNumResponse updateCartNum(UpdateCartNumRequest request) {
        UpdateCartNumResponse response = new UpdateCartNumResponse();
        /*
        这里不需要考虑limitNum字段(单个用户最大限数量)。
        前端做的，只要大于100就不能再增加；小于1时，再减就会循环到99件
        */
        RMap<Long, CartProductDto> map = redissonClient.getMap(request.getUserId().toString());
        CartProductDto cartProductDto = map.get(request.getItemId());
        if (cartProductDto == null) {
            response.setCode(ShoppingRetCode.REQUISITE_PARAMETER_NOT_EXIST.getCode());
            response.setMsg(ShoppingRetCode.REQUISITE_PARAMETER_NOT_EXIST.getMessage());
        }
        cartProductDto.setChecked(request.getChecked());
        cartProductDto.setProductNum(request.getNum().longValue());
        map.put(request.getItemId(), cartProductDto);

        response.setCode(ShoppingRetCode.SUCCESS.getCode());
        response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        return response;
    }


    /**
     * 选择购物车中的所有商品
     *
     * @param request
     * @return
     */
    @Override
    public CheckAllItemResponse checkAllCartItem(CheckAllItemRequest request) {
        CheckAllItemResponse response = new CheckAllItemResponse();
        try {
            RMap<Long, CartProductDto> rMap = redissonClient.getMap(request.getUserId().toString());
            Collection<CartProductDto> cartProductDtos = rMap.readAllValues();
            for (CartProductDto cartProductDto : cartProductDtos) {
                Long productId = cartProductDto.getProductId();
                cartProductDto.setChecked(request.getChecked());
                rMap.put(productId,cartProductDto);
            }
        }catch (Exception e){
            response.setCode(ShoppingRetCode.SYSTEM_ERROR.getCode());
            response.setMsg(ShoppingRetCode.SYSTEM_ERROR.getMessage());
            return response;
        }
        response.setCode(ShoppingRetCode.SUCCESS.getCode());
        response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        return response;
    }

    /**
     * 删除购物车中的商品
     *
     * @param request
     * @return
     */
    @Override
    public DeleteCartItemResponse deleteCartItem(DeleteCartItemRequest request) {
        DeleteCartItemResponse response = new DeleteCartItemResponse();
        log.info("deleteItem : {}" ,request);

        try {
            request.requestCheck();
            RMap<Object, Object> map = redissonClient.getMap(request.getUserId().toString());
            long fastRemove = map.fastRemove(request.getItemId());

            if (fastRemove == 1L){
                response.setCode(ShoppingRetCode.SUCCESS.getCode());
                response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
            }
        } catch (Exception e) {
            log.info("cartServiceImpl.deleteCartItem occur Exception",e);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
        }
        return response;
    }


    /**
     * 删除选中的商品
     *
     * @param request
     * @return
     */
    @Override
    public DeleteCheckedItemResposne deleteCheckedItem(DeleteCheckedItemRequest request) {
        DeleteCheckedItemResposne response = new DeleteCheckedItemResposne();
        Long userId = request.getUserId();
        RMap<Long, CartProductDto> map = redissonClient.getMap(userId.toString());
        Set<Long> longs = map.keySet();
        for (Long aLong : longs) {
            CartProductDto cartProductDto = map.get(aLong);
            if (cartProductDto.getChecked().equals("true")) {
                map.fastRemove(aLong);
            }
        }
        response.setCode(ShoppingRetCode.SUCCESS.getCode());
        response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        return response;
    }

    /**
     * 清空指定用户的购物车缓存(用户下完订单之后清理）
     *
     * @param request
     * @return
     */
    @Override
    public ClearCartItemResponse clearCartItemByUserID(ClearCartItemRequest request) {
        ClearCartItemResponse clearCartItemResponse = new ClearCartItemResponse();
        RMap<Long, CartProductDto> map = redissonClient.getMap(request.getUserId().toString());
        List<Long> productIds = request.getProductIds();
        for (Long productId : productIds) {
            map.fastRemove(productId);
        }
        clearCartItemResponse.setCode(ShoppingRetCode.SUCCESS.getCode());
        clearCartItemResponse.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        return clearCartItemResponse;
    }

}
